package org.lanzier.common.service.impl;

import java.io.BufferedOutputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.lanzier.common.exception.LanzierException;
import org.lanzier.common.form.RequestDataForm;
import org.lanzier.common.form.ResponseDataForm;
import org.lanzier.common.sqlparse.SqlResultForm;
import org.lanzier.common.utils.Environment;
import org.lanzier.common.utils.MapUtils;
import org.lanzier.common.utils.RegexUtils;
import org.lanzier.common.utils.XmlUtils;
import org.lanzier.common.web.httpobjects.HttpRequestObject;
import org.springframework.stereotype.Service;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

/**
 * @author lansb 业务处理service统一入口
 */
@Service("saveService")
public class SaveService extends AbstractService {

	private final String SELECT = "select";// 查询语句

	private final String INSERT_FILE = "insert_file";// 文件插入

	private final String DEL_FILE = "del_file";// 文件删除

	private final String EXECUTE = "execute";// 普通执行语句

	public ResponseDataForm service(RequestDataForm requestDataForm)
			throws Exception {
		ResponseDataForm rdf = new ResponseDataForm();// 存放返回结果
		Map<String, Object> urlSqlMap = requestDataForm.getUrlSqlMap();
		Map<String, String> simpleRequestMap = requestDataForm
				.getSimpleRequestMap();
		Map<String, List<HttpRequestObject>> multipleRequestMap = requestDataForm
				.getMultipleRequestMap();
		// 数据验证
		String validation = MapUtils.getString(urlSqlMap, "VALIDATION");
		if (!"".equals(validation)) {
			NodeList sqlNodes = XmlUtils.getNoteListByString(validation);
			Element element = null;
			for (int i = 0; i < sqlNodes.getLength(); i++) {
				Node child = sqlNodes.item(i);
				if (child.getNodeType() != Node.ELEMENT_NODE)
					continue;
				element = (Element) child;
				validator(element, multipleRequestMap, simpleRequestMap, rdf);
			}
		}
		// 执行业务sql
		String execSql = MapUtils.getString(urlSqlMap, "EXEC_SQL");
		if (!"".equals(execSql)) {
			NodeList sqlNodes = XmlUtils.getNoteListByString(execSql);
			Element element = null;
			for (int i = 0; i < sqlNodes.getLength(); i++) {
				Node child = sqlNodes.item(i);
				if (child.getNodeType() != Node.ELEMENT_NODE)
					continue;
				element = (Element) child;
				processRecord(element, multipleRequestMap, simpleRequestMap);
			}
		}
		return rdf;
	}

	private boolean validator(Element data,
			Map<String, List<HttpRequestObject>> multipleRequestMap,
			Map<String, String> simpleRequestMap, ResponseDataForm rdf)
			throws Exception {
		String field = data.getAttribute("field");// 验证的参数名称
		String method = data.getAttribute("method") == null ? "reg" : data
				.getAttribute("method");// 验证方法，reg/database为空时候为reg
		String msg = data.getAttribute("msg");// 提示信息
		boolean required = data.getAttribute("required") == null ? true
				: Boolean.parseBoolean(data.getAttribute("required"));// true/false是否必填,为空时候为true
		String reg = data.getAttribute("reg");// 正则表达式，可以为空，
		int maxlength = data.getAttribute("maxlength") == null ? -1 : Integer
				.parseInt(data.getAttribute("maxlength"));// 最大长度,数字，可以为空
		int minlength = data.getAttribute("minlength") == null ? -1 : Integer
				.parseInt(data.getAttribute("minlength"));// 最小长度,数字，可以为空
		String orisql = data.getAttribute("sql");// 验证方式为database，判断的sql
		boolean validatorResult = true;
		List<String> errorList = rdf.getErrorList();
		if (errorList != null) {
			errorList = new ArrayList<String>();
			rdf.setErrorList(errorList);
		}
		if (method.equals("database")) {
			SqlResultForm srf = sqlParse.parseString(orisql, simpleRequestMap);
			String result = jdbcDao.queryForString(srf.getParsedSql(), srf
					.getValueList().toArray());
			validatorResult = "0".equals(result) ? false : true;
		} else if (method.equals("reg")) {
			String value = simpleRequestMap.get(field);
			if ("".equals(value) && !required)
				return validatorResult;
			validatorResult = RegexUtils.match(reg, value);
			if (minlength > 0 && value.length() < minlength) {
				validatorResult = false;
			}
			if (maxlength > 0 && value.length() > maxlength) {
				validatorResult = false;
			}
		} else {
			throw new LanzierException(method
					+ "验证方法不存在，数据库验证请使用：database，正则表达式验证：reg。");
		}
		if (!validatorResult) {
			errorList.add(msg);
		}
		return validatorResult;
	}

	/**
	 * 一张表入n条记录，n根据参数中传送的iterfield字段（配置文件中配置）的个数 if(n=1) then singlerecord
	 * 
	 * @param element
	 * @param sourceMap
	 * @throws Exception
	 */
	private void processRecord(Element element,
			Map<String, List<HttpRequestObject>> multipleRequestMap,
			Map<String, String> simpleRequestMap) throws Exception {
		String operator = element.getAttribute("operator");// 操作类型，如果类型为
		String iterFields = element.getAttribute("iterfields");// roleid,privid可以为空，循环迭代标志，页面迭代的参数，多个用,号隔开；可以是页面直接提交多个数值或一个数值配合iterfieldsplit参数进行分解,如果为多个，必须保证页面提交的数值个数必须相等
		String iterFieldSplit = element.getAttribute("iterfieldsplit");// 可以为空，如果此参数不为空，将iterfield按此参数进行分解并迭代。iterfield=rights,iterFieldSplit=“,”，页面提交的rights参数值为101,102，迭代的次数为2
		String fileWname = element.getAttribute("filewname");
		fileWname = fileWname == null ? "" : fileWname;

		int iterSize = 1;
		String[] iterFieldArr = null;
		if (!"".equals(iterFields)) {
			iterFieldArr = iterFields.split(",");
			if ("".equals(iterFieldSplit)) {// 按照提交的数值个数进行循环
				iterSize = multipleRequestMap.get(iterFieldArr[0]).size();
			} else {
				iterSize = new String(multipleRequestMap.get(iterFieldArr[0])
						.get(0).getValue(), Environment.ENCODING)
						.split(iterFieldSplit).length;
			}
		}
		for (int i = 0; i < iterSize; i++) {// 循环的次数
			// 如果有迭代，准备迭代的数据，初始化simpleRequestMap值
			if (iterFieldArr != null) {
				for (String piterfield : iterFieldArr) {
					if ("".equals(iterFieldSplit)) {// 按照提交的数值个数进行循环
						simpleRequestMap.put(piterfield, new String(
								multipleRequestMap.get(piterfield).get(i)
										.getValue(), Environment.ENCODING));
					} else {// 取自分解后的值
						simpleRequestMap.put(piterfield, new String(
								multipleRequestMap.get(piterfield).get(0)
										.getValue(), Environment.ENCODING)
								.split(iterFieldSplit)[i]);
					}
				}
			}
			SqlResultForm srf = sqlParse.parseNode(element, simpleRequestMap);
			Object[] pramArr = srf.getValueList().toArray();
			String parsedSql = srf.getParsedSql();
			if("".equals(parsedSql)) return;
			if (this.SELECT.equalsIgnoreCase(operator)) {// 执行类型为查询，并且需要把查询结果注入multipleRequestMap和simpleRequestMap
				List<Map<String, Object>> rsList = jdbcDao.queryForList(
						parsedSql, pramArr);
				putRecordListToHashMap(rsList, multipleRequestMap,
						simpleRequestMap);
			} else if (this.EXECUTE.equalsIgnoreCase(operator)) {
				jdbcDao.execute(parsedSql, pramArr);
			} else if (this.INSERT_FILE.equalsIgnoreCase(operator)) {
				jdbcDao.execute(parsedSql, pramArr);
				// 插入附件
				saveFile(i, multipleRequestMap, fileWname);

			} else if (this.DEL_FILE.equalsIgnoreCase(operator)) {
				delFile(jdbcDao.queryForList(parsedSql, pramArr));
			}
		}

	}

	/**
	 * 保存附件
	 * 
	 * @param index
	 * @param multipleRequestMap
	 * @param filewname
	 * @throws Exception
	 */
	private void saveFile(int index,
			Map<String, List<HttpRequestObject>> multipleRequestMap,
			String filewname) throws Exception {
		String filename = jdbcDao
				.queryForString(
						"select save_file_name from sys_affix_tab t where t.id=(select seq_sys_affix2.curval from dual)",
						null);
		String path = filename.substring(0, filename.lastIndexOf("/"));
		HttpRequestObject hro = multipleRequestMap.get(filewname).get(index);
		byte[] bytes = hro.getValue();
		path = filename.substring(0, filename.lastIndexOf("/"));
		File file = new File(path);
		file.mkdirs();
		DataOutputStream dos = new DataOutputStream(new BufferedOutputStream(
				new FileOutputStream(filename)));
		dos.write(bytes, 0, bytes.length);
		dos.flush();
	}

	/**
	 * 根据查询结果集合删除附件
	 * 
	 * @param rsList
	 */
	private void delFile(List<Map<String, Object>> rsList) {
		for (Map<String, Object> rsMap : rsList) {
			for (Entry<String, Object> entity : rsMap.entrySet()) {
				String saveFileName = entity.getValue() == null ? "" : entity
						.getValue().toString();
				if (!"".equals(saveFileName)) {
					File file = new File(saveFileName);
					if (file.exists())
						file.delete();
				}
				break;
			}
		}

	}

	/**
	 * 将查询的结果集推送到系统的map中
	 *@param rsList
	 *@param multipleRequestMap
	 *@param simpleRequestMap
	 *@throws Exception
	 */
	private void putRecordListToHashMap(List<Map<String, Object>> rsList,
			Map<String, List<HttpRequestObject>> multipleRequestMap,
			Map<String, String> simpleRequestMap) throws Exception {
		if (rsList != null && rsList.size() > 0) {
			for (Map<String, Object> rsMap : rsList) {
				for (Entry<String, Object> entity : rsMap.entrySet()) {
					String key = entity.getKey();// key值默认为
					String value = entity.getValue() == null ? "" : entity
							.getValue().toString();
					HttpRequestObject hro = new HttpRequestObject();
					hro.setName(key);
					hro.setValue(value.getBytes(Environment.ENCODING));
					if (multipleRequestMap.containsKey(key)) {
						List<HttpRequestObject> hroList = multipleRequestMap
								.get(key);
						hroList.add(hro);
					} else {
						List<HttpRequestObject> hroList = new LinkedList<HttpRequestObject>();
						hroList.add(hro);
						multipleRequestMap.put(key, hroList);
					}
					simpleRequestMap.put(key, value);
				}
			}
		}
	}
}
